export interface App extends Micro {
  owner?: string
  version?: string
  logo?: string
  copyright?: string
  home?: any // 默认首页,
  homeLayout?: Layout
  homeProps?: Record<string, any>
  micros?: Record<string, Micro>
  groups?: Record<string, Group>  // 对【seed,action,home】进行分组的定义
  root?: any
  rootLayout?: Layout,
  rootProps?: Record<string, any>
  login?: any,
  loginLayout?: Layout
  loginProps?: Record<string, any>
  error?: any,
  errorLayout?: Layout
  errorProps?: Record<string, any>
  redirect?: any,
  redirectLayout?: Layout
  redirectProps?: Record<string, any>
}

export interface Micro extends Icon {
  name?: string
  label?: string
  comment?: string
  component?: any,
  layout?: Layout
  componentProps?: Record<string, any>
  homes?: Record<string, Home>
  seeds?: Record<string, Seed>
  actions?: Record<string, Action> // 独立行为
  libs?: string[]
}

export interface Home extends Icon {
  name?: string
  position?: SeedPosition[] // 入口位置
  mode?: 'popup' | 'content' // 显示模式：popup:弹窗显示，content: 内容区域显示
  label?: string
  comment?: string
  component?: any
  layout?: Layout,
  componentProps?: Record<string, any>
  popupProps?: Record<string, any>
  affix?: boolean
  hidden?: boolean
  breadcrumb?: boolean
  noTagsView?: boolean
}

export interface Seed extends Home {
  type?: SeedType
  idColumn?: string
  nameColumn?: string

  declares?: string[]
  searches?: string[]
  orders?: string[]

  checkLogin?: boolean
  checkAction?: boolean
  useKeyword?: boolean

  actions?: Record<string, Action>
  columns?: Record<string, Column>
  hasOne?: Record<string, HasOne>
  hasMany?: Record<string, HasMany>
  belongsTo?: Record<string, BelongsTo>
  habtm?: Record<string, Habtm>
  stats?: Record<string, Stat>
  groups?: Record<string, Group>  // 对【declare】进行分组的定义
}

export interface Icon {
  icon?: string
  color?: string
  size?: number
  hoverColor?: string
}

export interface Action extends Home {
  type?: ActionType
  toolbar?: string // 工具条上的操作入口,逗号分隔
  row?: string // 数据行上的操作入口,逗号分隔
  columnName?: string
  columnValue?: string | number
  columns?: Record<string, Column> // 这里定义的列可以覆盖通用列
  stats?: Record<string, Stat>

  seedName?: string // 独立行为依赖的seed名称
  origin?: 'app' | 'micro' | 'seed' // 来源
  
  declares?: string[]
  searches?: string[]
  orders?: string[]

  checkLogin?: boolean
  checkAction?: boolean
  useKeyword?: boolean

  confirm?: string | boolean // 二次确认提示信息

  onClick?: (action: Action, unit: Unit, row?: Record<string, any>) => void
  seed?: Seed
  micro?: Micro
  app?: App
}

export interface Relation {
  seedName: string
  selfSeed?: Seed
  targetSeed?: Seed
  selfColumn?: string
  targetColumn?: string
  label?: string
  comment?: string
}

export interface Cross {
  label?: string
  type?: RelationType
  columns?: Record<string, Column>
  rules?: Record<string, any>
  crosses?: Record<string, Cross>
}

export interface BelongsTo extends Relation {}

export interface HasOne extends BelongsTo {}

export interface HasMany extends HasOne {}

export interface Habtm extends HasMany {
  throughSeedName: string
  throughSeed?: Seed
  throughSelfColumn?: string
  throughTargetColumn?: string
}

/**
 * rel:
 * micro.seed.action 在服务【micro】下去找
 * .seed.action 在应用下去找
 * seed.action 在当前所在的服务下去找
 * action 在当前seed下去找
 */
export interface Column {
  name?: string
  type?: ColumnType
  label?: string
  comment?: string
  precision?: number
  required?: boolean
  defVal?: any
  length?: number
  min?: any
  max?: any
  options?: Record<string, string>
  rel?: string

  element?: any
  elementProps?: Record<string, any>
  isLarge?: boolean
  seed?: Seed
  micro?: Micro
  app?: App
}

export interface Stat {
  name?: string
  label?: string
  comment?: string
  type?: 'count'|'sum'|'avg'|'min'|'max'
  declare?: string // 统计申明
  searches?: string[] // 统计条件
}

export interface SearchColumn extends Column {
  op?: OpType
}

export interface Declared extends Record<string, Declared> {}

export interface Lib {
  name?: string
  label?: string
  comment?: string
  actions?: Record<string, Action>
  seeds?: Record<string, Seed>
}

export interface Group extends Icon {
  name?: string
  label?: string
  comment?: string
  /**
   * 用于【action,home,seed】和【declare】的分组
   * 1. 【action,home,seed】分组： items形如【app.micro.seed】组成的数组
   * 2. 【declare】分组：items为【declare】组成的数组
   */
  items?: string[]
}

export interface StatRef {
  show: () => void
  hide: () => void
  toggle: () => void
  visible: boolean
}

export interface SearchRef {
  show: () => void
  hide: () => void
  toggle: () => void
  visible: boolean
  length: number
}

export interface OrderRef {
  show: () => void
  hide: () => void
  toggle: () => void
  visible: boolean
}

export interface Unit {
  columns?: TableColumn[]
  searchData?: Record<string, any>
  orderData?: Record<string, OrderDirection>
  keyword?: string
  statData?: Record<string, any>
  currentRow?: Record<string, any>
  selectedRows?: Record<string, any>[]

  searchRef?: SearchRef
  orderRef?: OrderRef
  statRef?: StatRef
  refresh: () => void
}

/**
 * 表格的列定义
 */
export interface TableColumn extends Column {
  field: string
  hidden?: boolean
  orderDirection?: OrderDirection
}

// export interface Stats {
//   label?: string
//   comment?: string
//   value: any
// }

export interface Property {
  type: PropertyType
  value: Column | HasOne | BelongsTo | HasMany | Habtm
}

type AccountType = 'admin' | 'userUsername' | 'userCode' | 'tenantUsername' | 'tenantUserUsername' | 'tenantUserCode'

export interface TokenInfo {
  tokenName: string
  tokenValue: string
  isLogin: boolean
  loginId: string
  loginType: string
  tokenTimeout: number
  sessionTimeout: number
  tokenSessionTimeout: number
  tokenActiveTimeout: number
  loginDevice: string
}

export interface Account {
  type: AccountType // 账号类型
  value: string // 账号
  tenantname?: string // 租户号
  loginId: string // 登录ID
}

export interface Subject {
  account: Account
  name: string
  avatar?: string
  tokenInfo: TokenInfo
  positions?: Record<string, string>
  permissions: string[]
  fullPermissions: string[] // 能使用的全部权限，对于内用户来说是【*】,即全部，对于租户用户来说是租户所拥有的权限
}

export type Layout = {
  type?: ComponentType
  component?: any
  componentProps?: Record<string, any>
  cls?: string[],
  style?: Record<string, any>
  content?: string
  children?: Layout[]

  // action?: Action,
  // seed?: Seed
  // micro?: Micro
  // app?: App
}

export const ops = {
  isNull: '空',
  isNotNull: '非空',
  like: '匹配',
  likeLeft: '左匹配',
  likeRight: '右匹配',
  notLike: '非匹配',
  notLikeLeft: '非左匹配',
  notLikeRight: '非右匹配',
  eq: '等于',
  ne: '不等于',
  gt: '大于',
  ge: '大于等于',
  lt: '小于',
  le: '小于等于',
  in: '在...范围',
  notIn: '不在...范围',
  between: '在...之间',
  notBetween: '不在...之间'
}

export type SeedType = 'module' | 'through'
export type RelationType = 'hasOne' | 'belongsTo' | 'hasMany' | 'habtm'
export type PropertyType = RelationType | 'column'
export type GetVO = {
  type: PropertyType
  id: string
  name: string
  value?: any
  label?: string
  values?: Record<any, string>
}

export type ActionPosition = 'toolbar' | 'row' // 功能入口位置
export type SeedPosition = 'nav' | 'menu' | 'ucenter' // 模块入口位置

export type ShowPosition = 'dialog' | 'drawer' | 'card' | 'none'
export type LookupType = 'page' | 'tree' | 'list'

export type ActionType = 'page' | 'list' | 'save' | 'saves' | 'detail' | 'get' | 'set' | 'sets' | 'remove' | 'removes' | 'stat' | 'update' | 'updates' | 'belongsTo' | 'habtm' | 'importExcel' | 'exportExcel' | 'reset'
export const actionTypeOptions = {
  page: '分页列表',
  list: '普通列表',
  save: '保存',
  saves: '批量保存',
  detail: '详情',
  get: '获取',
  set: '设置',
  sets: '批量设置',
  remove: '删除',
  removes: '批量删除',
  stat: '统计',
  update: '更新',
  updates: '批量更新',
  importExcel: '导入excel',
  exportExcel: '导出excel',
  reset: '重置密码'
}
export type ComponentType = ActionType | 'login' | 'home' | 'seed' | 'error' | 'redirect' | 'root' | 'layout'

export type ColumnType = 'varchar' | 'char' | 'tinytext' | 'text' | 'mediumtext' | 'longtext'
  | 'tinyint' | 'smallint' | 'mediumint' | 'int' | 'bigint' | 'double' | 'float' | 'decimal'
  | 'bit' | 'enum' | 'set' | 'date' | 'year' | 'datetime' | 'timestamp'
  | 'file' | 'image' | 'avatar' | 'password' | 'icon' | 'qrcode'
  | 'tinyblob' | 'blob' | 'mediumblob' | 'longblob' | 'binary' | 'varbinary'
  | 'json' | 'color' | 'ref' | 'yesno' | 'sex' | 'age'
export const columnTypeOptions = {
  varchar: '变长字符串',
  char: '定长字符串',
  tinytext: '微文本',
  text: '文本',
  mediumtext: '中文本',
  longtext: '长文本',
  tinyint: '微整型',
  smallint: '小整型',
  mediumint: '中整型',
  int: '整型',
  bigint: '大整型',
  double: '双精度浮点数',
  float: '单精度浮点数',
  decimal: '定点小数',
  bit: '布尔',
  enum: '枚举',
  set: '集合',
  date: '日期',
  year: '年',
  datetime: '日期时间',
  timestamp: '时间戳',
  file: '文件',
  image: '图像',
  avatar: '头像',
  password: '密码',
  icon: '图标',
  qrcode: '二维码',
  tinyblob: '微二进制大对象',
  blob: '二进制大对象',
  mediumblob: '中二进制大对象',
  longblob: '长二进制大对象',
  binary: '定长二进制',
  varbinary: '变长二进制',
  json: 'JSON',
  color: '颜色',
  ref: '引用',
  yesno: '是否',
  sex: '性别',
  age: '年龄'
}

export type ElementType = ColumnType

export type OpType = 'isNull' | 'isNotNull' | 'like' | 'likeLeft' | 'likeRight' | 'notLike' | 'notLikeLeft' | 'notLikeRight'
  | 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'in' | 'notIn' | 'between' | 'notBetween'

// none: 无级联操作, setnull: 设置为null, force: 强制级联删除, check: 检查引用，如果有引用则不允许删除
export type Cascade = 'none' | 'setnull' | 'force' | 'check'

export type OrderDirection = 'asc' | 'desc'

export type MenuItem = {
  name?: string
  label: string
  path?: string
  icon?: string
  mode?: 'popup' | 'content'
  component?: any
  componentProps?: Record<string, any>
  children?: MenuItem[]
}

export type Tag = {
  name?: string
  label: string
  path?: string
  icon?: string  
  affix?: boolean
  noTagsView?: boolean
  noCache?: boolean
}

export interface OwnerAction {
  id: string
  name: string
  actions: string[]
}

export interface RoleAction extends OwnerAction {

}

export interface OrganizationAction extends OwnerAction {
  roleActions: RoleAction[]
}

export interface UserAction extends OwnerAction {
  roleActions: RoleAction[]
  positionActions: OrganizationAction[]
}

export const defineLayout = (layout: Layout) => layout
export const defineSeed = (seed: Seed) => seed
export function defineLib(lib: Lib) {
  if(lib.actions) {
    for(const actionName in lib.actions) lib.actions[actionName].name = actionName
  }

  return lib
}

export function isNumber(columnType: ColumnType) {
  return ['tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'double', 'float', 'decimal'].includes(columnType)
}

export function checkOpType(op: string) {
  const types = Object.keys(ops)
  if(!types.includes(op)) throw Error(`不支持的操作类型【${op}】`)
}

export function getOps(column?: Column) {
  return ops
}

// export function isActionType(s: string) {
//   return ['page','list','save','saves','detail','set','sets','remove','removes','update','updates','belongsTo','habtm','importExcel','exportExcel','reset'].includes(s)
// }